package com.shopping_back.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.shopping_back.mapper.*;
import com.shopping_back.pojo.dto.PromotionConfigDTO;
import com.shopping_back.pojo.entity.*;
import com.shopping_back.pojo.vo.SkuVO;
import com.shopping_back.service.IPromotionActivityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping_back.pojo.dto.PageDTO;
import com.shopping_back.pojo.dto.PromotionCreateDTO;
import com.shopping_back.pojo.dto.PromotionUpdateDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 促销活动表 服务实现类
 * </p>
 *
 * @author Jack
 * @since 2025-07-12
 */
@Service
@RequiredArgsConstructor
public class PromotionActivityServiceImpl extends ServiceImpl<PromotionActivityMapper, PromotionActivity> implements IPromotionActivityService {

    private final PromotionActivityMapper promotionActivityMapper;

    private final SeckillItemMapper seckillItemMapper;

    private final SkuMapper skuMapper;

    private final GroupbuyItemMapper groupbuyItemMapper;

    private final FullReductionItemMapper fullReductionItemMapper;

    private final ComboItemMapper comboItemMapper;

    private final ObjectMapper objectMapper;

    private final GroupbuyGroupMapper groupbuyGroupMapper;

    private final GroupbuyMemberMapper groupbuyMemberMapper;

    private final ComboMapper comboMapper;

    @Override
    public Map<String, Object> getPromotionsByType(Integer page, Integer size, Integer type) {
        Page<PromotionActivity> pageRequest = new Page<>(page, size);
        QueryWrapper<PromotionActivity> queryWrapper = new QueryWrapper<>();
        // 如果 type 不为空，添加类型过滤条件
        if (type != null) {
            queryWrapper.eq("type", type);
        }
        IPage<PromotionActivity> promotionActivityPage = promotionActivityMapper.selectPage(pageRequest, queryWrapper);
        Map<String, Object> data = new HashMap<>();
        data.put("list", promotionActivityPage.getRecords());
        data.put("total", promotionActivityPage.getTotal());
        return data;
    }

    public List<SkuVO> getSkus(Long merchantId) {
        return skuMapper.selectSkuByMerchantId(merchantId);
    }

    public void addSeckillItem(SeckillItem seckillItem) {
        Sku sku = skuMapper.selectById(seckillItem.getSkuId());
        if (sku == null) {
            throw new IllegalArgumentException("SKU 不存在");
        }
        if (seckillItem.getSeckillPrice().compareTo(sku.getPrice()) > 0) {
            throw new IllegalArgumentException("秒杀价格不能高于原价 ¥" + sku.getPrice());
        }
        if (seckillItem.getSeckillStock() > sku.getStock()) {
            throw new IllegalArgumentException("秒杀库存不能超过剩余库存 " + sku.getStock());
        }
        seckillItemMapper.insert(seckillItem);
        updatePromotionScope(seckillItem.getActivityId(), seckillItem.getSkuId());
    }

    public void addGroupbuyItem(GroupbuyItem item) {
        Sku sku = skuMapper.selectById(item.getSkuId());
        if (sku == null) {
            throw new IllegalArgumentException("SKU 不存在");
        }
        if (item.getGroupPrice().compareTo(sku.getPrice()) > 0) {
            throw new IllegalArgumentException("团购价格不能高于原价 ¥" + sku.getPrice());
        }
        item.setCreateTime(LocalDateTime.now());
        groupbuyItemMapper.insert(item);
        updatePromotionScope(item.getActivityId(), item.getSkuId());
    }

    public void addFullReductionItem(FullReductionItem item) {
        PromotionActivity promotionActivity = promotionActivityMapper.selectById(item.getActivityId());
        item.setThreshold(promotionActivity.getThreshold());
        item.setDiscount(promotionActivity.getDiscount());
        System.out.println(item);
        Sku sku = skuMapper.selectById(item.getSkuId());
        if (sku == null) {
            throw new IllegalArgumentException("SKU 不存在");
        }
        fullReductionItemMapper.insert(item);
        updatePromotionScope(item.getActivityId(), item.getSkuId());

    }

    public void addComboItem(Long activityId, Long skuId) {
        Combo combo = new Combo();
        combo.setActivityId(activityId);
        comboMapper.insert(combo);
        Combo combo1 = comboMapper.selectOne(new LambdaQueryWrapper<Combo>().eq(Combo::getActivityId, activityId));
        ComboItem comboItem = new ComboItem();
        comboItem.setComboId(combo1.getId());
        comboItem.setSkuId(skuId);
        comboItem.setQuantity(1);
        comboItemMapper.insert(comboItem);
        updatePromotionScope(activityId, skuId);
    }

    public List<?> getPromotionItems(Long activityId, Integer type) {
        switch (type) {
            case 1:
                return seckillItemMapper.selectSeckillItems(activityId);
            case 2:
                return groupbuyItemMapper.selectGroupbuyItems(activityId);
            case 3:
                return fullReductionItemMapper.selectFullReductionItems(activityId);
            case 4:
                return comboItemMapper.selectComboItems(activityId);
            default:
                throw new IllegalArgumentException("无效的活动类型");
        }
    }

    public void deletePromotionItem(Long activityId, Long skuId, Integer type) {
        switch (type) {
            case 1:
                seckillItemMapper.delete(new LambdaQueryWrapper<SeckillItem>()
                        .eq(SeckillItem::getActivityId, activityId)
                        .eq(SeckillItem::getSkuId, skuId));
                break;
            case 2:
                groupbuyItemMapper.delete(new LambdaQueryWrapper<GroupbuyItem>()
                        .eq(GroupbuyItem::getActivityId, activityId)
                        .eq(GroupbuyItem::getSkuId, skuId));
                break;
            case 3:
                fullReductionItemMapper.delete(new LambdaQueryWrapper<FullReductionItem>()
                        .eq(FullReductionItem::getActivityId, activityId)
                        .eq(FullReductionItem::getSkuId, skuId));
                break;
            case 4:
                // 1. 根据 activityId 查询对应的 comboId
                Combo combos = comboMapper.selectOne(new LambdaQueryWrapper<Combo>()
                        .eq(Combo::getActivityId, activityId));

                // 2. 如果存在 comboId，则根据 comboId 和 skuId 删除 combo_item 记录
                if (combos != null) {
                    comboItemMapper.delete(new LambdaQueryWrapper<ComboItem>()
                            .in(ComboItem::getComboId, combos.getId())
                            .eq(ComboItem::getSkuId, skuId));
                }
                break;
            default:
                throw new IllegalArgumentException("无效的活动类型");
        }
        updatePromotionScope(activityId, skuId, true);
    }

    private void updatePromotionScope(Long activityId, Long skuId) {
        updatePromotionScope(activityId, skuId, false);
    }

    private void updatePromotionScope(Long activityId, Long skuId, boolean remove) {
        PromotionActivity activity = promotionActivityMapper.selectById(activityId);
        List<Long> skuIds = new ArrayList<>();
        try {
            if (activity.getScopeJson() != null && !activity.getScopeJson().isEmpty()) {
                // 尝试直接解析为 List<Long>
                try {
                    skuIds = objectMapper.readValue(activity.getScopeJson(), new TypeReference<List<Long>>() {});
                } catch (MismatchedInputException e) {
                    // 如果是 JSON 对象，尝试提取数组字段（如 "ids"）
                    ObjectNode jsonNode = objectMapper.readValue(activity.getScopeJson(), ObjectNode.class);
                    if (jsonNode.has("ids") && jsonNode.get("ids").isArray()) {
                        skuIds = objectMapper.convertValue(jsonNode.get("ids"), new TypeReference<List<Long>>() {});
                    } else {
                        throw new IllegalArgumentException("scopeJson 格式无效，期望 JSON 数组或包含 ids 数组的对象");
                    }
                }
            }
            if (remove) {
                skuIds.remove(skuId);
            } else if (!skuIds.contains(skuId)) {
                skuIds.add(skuId);
            }
            activity.setScopeJson(objectMapper.writeValueAsString(skuIds));
            promotionActivityMapper.updateById(activity);
        } catch (Exception e) {
            throw new RuntimeException("更新活动范围失败: " + e.getMessage(), e);
        }
    }

    @Override
    public PageDTO<PromotionActivity> listPage(Integer pageNum, Integer pageSize, String name, String type) {
        Page<PromotionActivity> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<PromotionActivity> qw = new LambdaQueryWrapper<>();
        if (name != null && !name.isBlank()) {
            qw.like(PromotionActivity::getName, name.trim());
        }
        if (type != null && !type.isBlank()) {
            qw.eq(PromotionActivity::getType, type);
        }
        qw.orderByDesc(PromotionActivity::getCreateTime);
        Page<PromotionActivity> res = this.page(page, qw);

        PageDTO<PromotionActivity> dto = new PageDTO<>();
        dto.setList(res.getRecords());
        dto.setTotal(res.getTotal());
        dto.setCurrentPage((int) res.getCurrent());
        dto.setPageSize((int) res.getSize());
        return dto;
    }

    @Override
    @Transactional
    public void create(PromotionCreateDTO dto) {
        if (dto.getStartTime().isAfter(dto.getEndTime())) {
            throw new RuntimeException("开始时间不能晚于结束时间");
        }

        PromotionActivity pa = new PromotionActivity();
        pa.setName(dto.getName());
        pa.setType(dto.getType());
        pa.setStartTime(dto.getStartTime());
        pa.setEndTime(dto.getEndTime());
        pa.setStatus(dto.getStatus() == null ? 1 : dto.getStatus());
        // scope_json / config_json 暂不处理
        this.save(pa);
    }

    @Override
    @Transactional
    public void updateBasic(PromotionUpdateDTO dto) {
        if (dto.getStartTime().isAfter(dto.getEndTime())) {
            throw new RuntimeException("开始时间不能晚于结束时间");
        }

        PromotionActivity pa = this.getById(dto.getId());
        if (pa == null) throw new RuntimeException("活动不存在");

        // type 不允许改
        pa.setName(dto.getName());
        pa.setStartTime(dto.getStartTime());
        pa.setEndTime(dto.getEndTime());

        this.updateById(pa);
    }

    @Transactional
    public void deleteCascade(Long id) {
        PromotionActivity pa = this.getById(id);
        if (pa == null) return;

        Integer type = pa.getType(); // 确保是 Integer
        switch (type) {
            case 1 -> { // 秒杀
                seckillItemMapper.delete(
                        new LambdaQueryWrapper<SeckillItem>()
                                .eq(SeckillItem::getActivityId, id)
                );
            }
            case 2 -> { // 团购
                // 1) 删 groupbuy_item 规则
                List<GroupbuyItem> items = groupbuyItemMapper.selectList(
                        new LambdaQueryWrapper<GroupbuyItem>()
                                .eq(GroupbuyItem::getActivityId, id)
                );
                if (!items.isEmpty()) {
                    List<Long> skuIds = items.stream()
                            .map(GroupbuyItem::getSkuId)
                            .toList();

                    List<GroupbuyGroup> groups = groupbuyGroupMapper.selectList(
                            new LambdaQueryWrapper<GroupbuyGroup>()
                                    .in(GroupbuyGroup::getItemSkuId, skuIds)
                    );
                    if (!groups.isEmpty()) {
                        List<Long> groupIds = groups.stream().map(GroupbuyGroup::getId).toList();

                        groupbuyMemberMapper.delete(
                                new LambdaQueryWrapper<GroupbuyMember>()
                                        .in(GroupbuyMember::getGroupId, groupIds)
                        );
                        groupbuyGroupMapper.delete(
                                new LambdaQueryWrapper<GroupbuyGroup>()
                                        .in(GroupbuyGroup::getId, groupIds)
                        );
                    }
                    groupbuyItemMapper.delete(
                            new LambdaQueryWrapper<GroupbuyItem>()
                                    .eq(GroupbuyItem::getActivityId, id)
                    );
                }
            }
            case 3 -> { // 满减
                fullReductionItemMapper.delete(
                        new LambdaQueryWrapper<FullReductionItem>()
                                .eq(FullReductionItem::getActivityId, id)
                );
            }
            case 4 -> { // 套餐
                comboItemMapper.delete(
                        new LambdaQueryWrapper<ComboItem>()
                                .eq(ComboItem::getActivityId, id)
                );
            }
            default -> {}
        }

        // 最后删活动本身
        this.removeById(id);
    }


    public void updatePromotionConfig(PromotionConfigDTO config) {
        PromotionActivity activity = promotionActivityMapper.selectById(config.getActivityId());
        if (activity == null) {
            throw new IllegalArgumentException("活动不存在");
        }
        if (activity.getType() == 3) { // 满减活动
            if (config.getThreshold() == null || config.getDiscount() == null) {
                throw new IllegalArgumentException("满减活动需提供门槛和折扣金额");
            }
            if (config.getThreshold().compareTo(BigDecimal.ZERO) <= 0) {
                throw new IllegalArgumentException("满减门槛必须大于0");
            }
            if (config.getDiscount().compareTo(BigDecimal.ZERO) <= 0) {
                throw new IllegalArgumentException("折扣金额必须大于0");
            }

            FullReductionItem fullReductionItem = fullReductionItemMapper.selectOne(new LambdaQueryWrapper<FullReductionItem>()
                            .eq(FullReductionItem::getActivityId, config.getActivityId()));
            fullReductionItem.setThreshold(config.getThreshold());
            fullReductionItem.setDiscount(config.getDiscount());
            activity.setThreshold(config.getThreshold());
            activity.setDiscount(config.getDiscount());
        } else if (activity.getType() == 4) { // 套餐活动
            if (config.getComboPrice() == null) {
                throw new IllegalArgumentException("套餐活动需提供套餐价格");
            }
            if (config.getComboPrice().compareTo(BigDecimal.ZERO) <= 0) {
                throw new IllegalArgumentException("套餐价格必须大于0");
            }
            activity.setComboPrice(config.getComboPrice());
            Combo combo = comboMapper.selectOne(new LambdaQueryWrapper<Combo>()
                    .eq(Combo::getActivityId, config.getActivityId()));
            combo.setComboPrice(config.getComboPrice());
            comboMapper.updateById(combo);
        } else {
            throw new IllegalArgumentException("仅满减或套餐活动可修改配置");
        }
        promotionActivityMapper.updateById(activity);
    }

    @Override
    public List<SkuVO> getSkusByAd() {
        return skuMapper.selectSkuWithSpuTitle();
    }
}
